import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.geom.Rectangle;
import flash.geom.Point;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.display.Sprite;
import flash.ui.Keyboard;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.filters.GlowFilter;
import haxe.FastList;
import flash.events.MouseEvent;
import flash.net.SharedObject;
import flash.Lib;
import haxe.Log;

import flash.utils.Timer;
import haxe.Timer;
import flash.events.Event;
import flash.display.MovieClip;
import flash.media.SoundChannel;


import Images; 
import Sounds; 
import MovieClips;
import Blob;
import Character;
import Scene;
import TextArea;
import InstructionPage;
import CreditsPage;
import OptionsPage;
import SoundPlayer;
import PauseMenu;

class Main extends Sprite{
private var ground : Int;
private var currentLevel : Int;
private var Scenes : Array<Scene>;
//Because the levels are so similiar i can do this. It's probably be to have a class for each level that inherents from the scence. 
private var Level1 : Scene;
private var Level2 : Scene;
private var Level3 : Scene;
private var Level4 : Scene;
private var Level5 : Scene;
private var Level6 : Scene;
private var Level7 : FinalScene;
private var State : String;
private var savedData:SharedObject;
private var ContinueGameButton:Sprite;
private var StartGameButton:Sprite;
private var MainMenuButton:Sprite;
private var InstructionsButton:Sprite;
private var CreditsButton:Sprite;
private var OptionsButton:Sprite;
private var Title:TextField;

private var label1:TextField;
private var Zombie:Sprite;
var myTimer:Timer;
var music:BackgroundMusic;            
private var player:SoundPlayer;
var preloader:PreloaderHost;
private var Background : Bitmap;
public var Instruction : InstructionPage;
public var Credit: CreditsPage;
public var OptionsMenu : OptionsPage;
var pausePosition:Float;
//             music.play();
var volume:Bool;
var sound:Bool;
var framerate:Int;

var MyCharacter : Character;
public function new(){
super();
Scenes = [];
getLevelData();

//inPostion,inMoveSpeed,inJumpSpeed,inAttackSpeed,inHealth:Int
initLevels();

//Add Main to Current Flash
flash.Lib.current.addChild(this);
//Create Menu (own Class?)
Title = new TextField();
    
  Title.x = 50; Title.y = 20;
  Title.width = 540; Title.height = 420;
  Title.multiline = true;
  var myFormat:TextFormat = new TextFormat();
  myFormat.size = 25;
  myFormat.align = TextFormatAlign.CENTER;
  Title.defaultTextFormat = myFormat;
  
  Title.htmlText = "Death By Nescience";

//It seems like there should be a better way to add a bitmap to a Sprite than filling the background with the bitmap. But this works.
StartGameButton = new Sprite();
StartGameButton.graphics.beginBitmapFill(new StartGame());
StartGameButton.graphics.drawRect(0, 0, 250 ,48);
StartGameButton.x = 195;
StartGameButton.y = 75;

StartGameButton.buttonMode = true;
StartGameButton.addEventListener(MouseEvent.CLICK, onStartGameButtonClick);

ContinueGameButton = new Sprite();

ContinueGameButton.graphics.beginBitmapFill(new ContinueGame());
ContinueGameButton.graphics.drawRect(0, 0, 250 ,48);
ContinueGameButton.x = 195;
ContinueGameButton.y = 145;

ContinueGameButton.buttonMode = true;
ContinueGameButton.addEventListener(MouseEvent.CLICK, onContinueGameButtonClick);


InstructionsButton = new Sprite();
InstructionsButton.graphics.beginBitmapFill(new Instructions());
InstructionsButton.graphics.drawRect(0, 0, 250 ,48);
InstructionsButton.x = 195;
InstructionsButton.y = 215;

InstructionsButton.buttonMode = true;
InstructionsButton.addEventListener(MouseEvent.CLICK, onInstrutionsButtonClick);

Instruction = new InstructionPage();
Instruction.addEventListener("Back",onInstrutionsBack);

CreditsButton = new Sprite();
CreditsButton.graphics.beginBitmapFill(new Credits());
CreditsButton.graphics.drawRect(0, 0, 250 ,48);
CreditsButton.x = 195;
CreditsButton.y = 285;

CreditsButton.buttonMode = true;
CreditsButton.addEventListener(MouseEvent.CLICK, onCreditsButtonClick);

Credit = new CreditsPage();
Credit.addEventListener("Back",onCreditsBack);

OptionsButton = new Sprite();
OptionsButton.graphics.beginBitmapFill(new Options());
OptionsButton.graphics.drawRect(0, 0, 250 ,48);
OptionsButton.x = 195;
OptionsButton.y = 355;

OptionsButton.buttonMode = true;
OptionsButton.addEventListener(MouseEvent.CLICK, onOptionsButtonClick);

OptionsMenu = new OptionsPage();
OptionsMenu.addEventListener("Back",onOptionsMenuBack);
OptionsMenu.addEventListener("ResetSavedData",onOptionsMenuResetSavedData);
OptionsMenu.addEventListener("VolumeToggle",onOptionsMenuVolumeToggle);
OptionsMenu.addEventListener("SoundEffectsToggle",onOptionsMenuSoundEffectsToggle);
//this.addEventListener(Event.ENTER_FRAME, OnEnter);
myTimer = new Timer(12);
  myTimer.addEventListener("timer", OnEnter);
  myTimer.start();

  label1 = new TextField();
  label1.x = 0; label1.y = 0;
  label1.width = 640; label1.height = 100;
  label1.autoSize = TextFieldAutoSize.CENTER;

Zombie = new Sprite();
Zombie.graphics.beginBitmapFill(new ZombieStand());
Zombie.graphics.drawRect(0, 0, 46,52);
Zombie.x = 300;
Zombie.y = 75;

MainMenuButton  = new Sprite();
MainMenuButton.graphics.beginBitmapFill(new MainMenu());
MainMenuButton.graphics.drawRect(0, 0, 250 ,48);
MainMenuButton.x = 200;
MainMenuButton.y = 135;
MainMenuButton.buttonMode = true;
MainMenuButton.addEventListener(MouseEvent.CLICK, onMainMenuButtonClick);

//The State Will determine whether to load a level, or show Main Menu, or whatever.  Used in the OnEnterEvent.
State = "InitLoad";
//State = "LoadMainMenu";
music = new BackgroundMusic();
preloader = new PreloaderHost();
Background = new Bitmap(new SunBackground());
player = new SoundPlayer(music);

volume = true;
sound = true;

//preloader.addEventListener(Event.ENTER_FRAME, OnMovieEnter);
}

function loadMenu()
{
  addChild(Background);
  addChild(Title);
  addChild(StartGameButton);
  addChild(ContinueGameButton);
  addChild(InstructionsButton);
  addChild(CreditsButton);
  addChild(OptionsButton);
}
function removeMenu()
{
  removeChild(Title);
  removeChild(StartGameButton);
  removeChild(ContinueGameButton);
  removeChild(Background);
  removeChild(InstructionsButton);
  removeChild(CreditsButton);
  removeChild(OptionsButton);
}
function loadTryAgainMenu(text:String)
{
  addChild(label1);
  label1.htmlText = "<font size='15'>" + text + "</font>";
  addChild(MainMenuButton);
  addChild(Zombie);
  player.stop();
}
function removeTryAgainMenu()
{
 removeChild(label1);
 removeChild(MainMenuButton);
 removeChild(Zombie);
}
function initLevels()
{

//Postion, MoveSpeed, JumpSpeed, AttackSpeed, Health, Bitmap)

}

function OnEnter(e:flash.events.Event)
{
if(State == "LoadMainMenu")
{
 loadMenu();
 State = "MainMenu";
}
if(State == "MainMenu" )
   {
     return;
   }
if(State == "TryAgain")
  {
    AnimateZombie();
    return;
  }
if(State == "InitLoad")
  {
   
    addChild(preloader);
    preloader.play();
    State = "InitLoading";
  }
if(State == "InitLoading")
   { 
    //Always Playing. Possible error with swfmill
    //Skipping for now.
 
    if(!preloader.playing)
       {
        preloader.stop();
        removeChild(preloader);
        State = "LoadMainMenu";
       }

   }
if(State == "Loading")
   {
    player.play(pausePosition);
    loadCurrentLevel();
   }
if(State == "Playing")
   {
    if(Scenes[currentLevel-1] != null)
    {
      if(Scenes[currentLevel-1].running)
      {
      if(!volume)
      {
	 pausePosition = player.getPosition();
         player.stop();
         
      }
      else
      {
        player.play(pausePosition);
      }
      return;
      }
      if(Scenes[currentLevel-1].victory == "Victory")
      {
      currentLevel++;
      savedData.data.Level = currentLevel;
      savedData.data.SoundPosition = player.getPosition();
      savedData.flush();
      }
      else if(Scenes[currentLevel-1].victory == "Loss")
      {
      loadTryAgainMenu("You Lose");
      State = "TryAgain";
      return;
      }
      else if(Scenes[currentLevel-1].victory == "GaveUp")
      {
      savedData.data.Level = currentLevel;
      savedData.data.SoundPosition = player.getPosition();
      savedData.flush();
      var BeatLevel:String;
      if(currentLevel <= 6)
        {
	  BeatLevel = "level " + currentLevel;
        }
      else
       {
	  BeatLevel = "The Game";
       }
      loadTryAgainMenu("You became a Zombie. Yay! and beat " + BeatLevel);
      State = "TryAgain";
      return;
      } 
        
    }
    loadCurrentLevel();
   }
if(State == "Won")
{
loadTryAgainMenu("You Won");
State = "TryAgain";
}
// try
// {
// //             var req:flash.net.URLRequest = new flash.net.URLRequest("http://av.adobe.com/podcast/csbu_dev_podcast_epi_2.mp3");
// //             
// //             Sound.load(req);
// var music = new BackgroundMusic();            
//             music.play();
// }
// catch (err:flash.Error)
// {
// trace(err.message);
// }


}
public function AnimateZombie()
{
var randomNumber = Std.random(24);
if(randomNumber == 1)
  Zombie.x = Zombie.x + 5;
if(randomNumber == 2)
  Zombie.x = Zombie.x - 5;

}

//Loads Level based on Current Level
public function loadCurrentLevel() : Bool
{
if(currentLevel <= 1)
{
var characters = new FastList<Character>();
//Postion, MoveSpeed, JumpSpeed, AttackSpeed, Health, Bitmap)
  characters.add(new MainCharacter(new Point(300,374),25,250,10,50,25));
  characters.add(new EnemyCharacter(new Point(100,374),1,0,50,25,5));
var Text = new FastList<TextArea>();
Text.add(new TextArea("<font color='#009900' size='25'>Give Up!</font>",0x28A328));
  Level1 = new Scene(new SunBackground(),Text,characters);
  Scenes[currentLevel-1] = Level1;
  State = "Playing";
}
else if (currentLevel == 2)
{
var characters2 = new FastList<Character>();
//Pos,Move,Jump:AttackSpeed,Health,AttackPower
  characters2.add(new MainCharacter(new Point(300,374),15,225,20,45,23));
  characters2.add(new EnemyCharacter(new Point(100,374),1,0,50,25,5));
  characters2.add(new EnemyCharacter(new Point(500,374),1,0,50,25,5));
var Text = new FastList<TextArea>();
Text.add(new TextArea("<font color='#009900' size='25'>Being a zombie ain't so bad.</font>",0x28A328));
Text.add(new TextArea("<font color='#009900' size='25'>All you worry about is eating your next meal.</font>",0x28A328));
Text.add(new TextArea("<font color='#009900' size='25'>Join us! Being a zombie is bliss!</font>",0x28A328));

  Level2 = new Scene(new SunBackground2(),Text,characters2);
  Scenes[currentLevel-1]=Level2;
  State = "Playing";
}
else if (currentLevel == 3)
{
  var characters3= new FastList<Character>();
  characters3.add(new MainCharacter(new Point(100,374),10,200,30,40,20));
  characters3.add(new EnemyCharacter(new Point(500,374),1,0,50,25,5));
var Text = new FastList<TextArea>();
Text.add(new TextArea("<font color='#009900' size='25'>...</font>",0x28A328));
Text.add(new TextArea("<font color='#009900' size='25'>I'm sorry, Please don't kill me.</font>",0x28A328));
 Level3 = new Scene(new SunBackground3(),Text,characters3);
  Scenes[currentLevel-1]=Level3;
  State = "Playing";
}
else if (currentLevel == 4)
{
  currentLevel;
  var characters3= new FastList<Character>();
  characters3.add(new MainCharacter(new Point(100,374),7,160,40,35,16));

  characters3.add(new EnemyCharacter(new Point(500,374),1,0,50,25,5));
var Text = new FastList<TextArea>();
Text.add(new TextArea("<font color='#009900' size='25'>Isn't it tiring fighting zombie?</font>",0x28A328));
Text.add(new TextArea("<font color='#009900' size='25'>Just Give up.</font>",0x28A328));
  Level4 = new Scene(new SunBackground4(),Text,characters3);
  Scenes[currentLevel-1]=Level4;
  State = "Playing";
}
else if (currentLevel == 5)
{
  currentLevel;
  var characters= new FastList<Character>();
  characters.add(new MainCharacter(new Point(100,374),5,125,50,30,10));
  characters.add(new EnemyCharacter(new Point(500,374),1,0,50,25,5));
var Text = new FastList<TextArea>();
Text.add(new TextArea("<font color='#009900' size='25'>What's so great about being human?</font>",0x28A328));
  Level5 = new Scene(new SunBackground5(),Text,characters);
  Scenes[currentLevel-1]=Level5;
  State = "Playing";
}
else if (currentLevel == 6)
{
  currentLevel;
  var characters= new FastList<Character>();
  characters.add(new MainCharacter(new Point(100,374),3,100,60,27,7));

  characters.add(new EnemyCharacter(new Point(500,374),1,0,50,25,5));
var Text = new FastList<TextArea>();
Text.add(new TextArea("<font color='#009900' size='25'>Do you something against zombies?</font>",0x28A328));
Text.add(new TextArea("<font color='#009900' size='25'>Do you think you're better than me?</font>",0x28A328));
  Level6 = new Scene(new SunBackground6(),Text,characters);
  Scenes[currentLevel-1]=Level6;
  State = "Playing";
}
else if (currentLevel == 7)
{
  currentLevel;
  var characters= new FastList<Character>();
  characters.add(new MainCharacter(new Point(100,374),1,0,50,25,5));

  characters.add(new BossCharacter(new Point(500,374),100,300,3,9001,100));//What?
  var Text = new FastList<TextArea>();
  Text.add(new TextArea("<font color='#000000' size='25'>Boss: So you've finally arrived.\nGive Up on this meaningless quest. Join me.</font>",0x28A328));
  Text.add(new TextArea("<font color='#FFFFFF' size='25'>Guy: Ummm...No.</font>",0x28A328));
  Text.add(new TextArea("<font color='#FFFFFF' size='25'>Did you think you could defeat me\nwith progessively harder zombies.\n You're Pathetic.</font>",0x28A328));
  Text.add(new TextArea("<font color='#000000' size='25'>hahaha.</font>",0x28A328));
  Text.add(new TextArea("<font color='#000000' size='25'>They weren't progressively harder.\nYou're just getting weaker.</font>",0x28A328));
  Text.add(new TextArea("<font color='#FFFFFF' size='25'>What?</font>",0x28A328));
  Text.add(new TextArea("<font color='#000000' size='25'>I mean it was pretty obivous.  Give up!\nEven if you can defeat me, there will be someone else.\nYou can't defeat the whole world</font>",0x28A328));
  Text.add(new TextArea("<font color='#FFFFFF' size='25'>I can, and I will</font>",0x28A328));
  player.stop();
  Level7 = new FinalScene(new SunsetBackground(),Text,characters);
  Scenes[currentLevel-1]=Level7;
  State = "Playing";
}
else if(currentLevel > 7)
{
  //Beat All Levels.
  State = "Won";
  return false;
}
//Level1.Load();
Scenes[currentLevel-1].Load(volume,sound);
Scenes[currentLevel-1].pauseMenu.renderVolume(volume);
Scenes[currentLevel-1].pauseMenu.renderSoundEffects(sound);
Scenes[currentLevel-1].addEventListener("VolumeToggle",onSceneVolumeToggle);
Scenes[currentLevel-1].addEventListener("SoundEffectsToggle",onSceneSoundEffectsToggle);
return true;
}


public function getLevelData()
{
  currentLevel = 1;
  pausePosition = 0;
  //Load Save Data
  savedData = SharedObject.getLocal("LevelData");
  if(savedData.data.Level != null)
  {
    currentLevel = savedData.data.Level;
    pausePosition = savedData.data.SoundPosition;
  }
}
public function removeClip(preloader)
{
 removeChild(preloader);
}
private function onStartGameButtonClick(event:MouseEvent) {
currentLevel = 1;
pausePosition = 0;
removeMenu();
State = "Loading";
}

private function onContinueGameButtonClick(event:MouseEvent) {
removeMenu();
State = "Loading";
}

private function onMainMenuButtonClick(event:MouseEvent) {
removeTryAgainMenu();
State = "LoadMainMenu";
}
private function onInstrutionsButtonClick(event:MouseEvent) {
removeMenu();
addChild(Instruction);
}

private function onCreditsButtonClick(event:MouseEvent) {
removeMenu();
addChild(Credit);
}

private function onOptionsButtonClick(event:MouseEvent) {
removeMenu();
addChild(OptionsMenu);
OptionsMenu.renderVolume(volume);
OptionsMenu.renderSoundEffects(sound);
}

private function onInstrutionsBack(event:InstructionPageEvent)
{
removeChild(Instruction);
loadMenu();
}

private function onOptionsMenuBack(event:OptionsPageEvent)
{
removeChild(OptionsMenu);
loadMenu();
}
private function onOptionsMenuVolumeToggle(event:OptionsPageEvent)
{
volume = !volume;
OptionsMenu.renderVolume(volume);
}
private function onOptionsMenuSoundEffectsToggle(event:OptionsPageEvent)
{
sound = !sound;
OptionsMenu.renderSoundEffects(sound);
}

private function onSceneVolumeToggle(event:PauseMenuEvent)
{
volume = !volume;
Scenes[currentLevel-1].volume = volume;
Scenes[currentLevel-1].pauseMenu.renderVolume(volume);
}
private function onSceneSoundEffectsToggle(event:PauseMenuEvent)
{
sound = !sound;
Scenes[currentLevel-1].sound = sound;
Scenes[currentLevel-1].pauseMenu.renderSoundEffects(sound);
}
private function onOptionsMenuResetSavedData(event:OptionsPageEvent)
{
      savedData.data.Level = 1;
      savedData.data.SoundPosition = 0;
      savedData.flush();
      getLevelData();
      pausePosition = 0;
      currentLevel = 1;
}
private function onCreditsBack(event:CreditsPageEvent)
{
removeChild(Credit);
loadMenu();
}

//Couldn't get preloader to work.
	    static function onEnterFrame(event : Event)
	    {
	        Log.trace("Downloaded " + Lib.current.root.loaderInfo.bytesLoaded + " of " + Lib.current.root.loaderInfo.bytesTotal + " bytes");
	 
	        if (Lib.current.root.loaderInfo.bytesLoaded >= Lib.current.root.loaderInfo.bytesTotal)
	        {
	            Lib.current.root.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
	            Log.trace("Preloading finished");
	            Lib.current.gotoAndStop("start");
                  // new Images();
	          var mainInstance:Main = new Main();
	        }
	    }

    static function main() {
// Log.trace("Starting preloader");
  //Lib.current.root.addEventListener(Event.ENTER_FRAME, onEnterFrame);
 new Main();
      // Create the request object...
//       var loader = new flash.display.Loader();
//       // When the image is ready, instanciate the game class...
//       loader.contentLoaderInfo.addEventListener(flash.events.Event.COMPLETE,
//           function(_) { new Main(untyped loader.content.bitmapData); });
//       // Fire off the request and wait...
//       loader.load(new flash.net.URLRequest("img/file.gif"));
        //new Main();    
      
	
    }
}